﻿#pragma once

#include <string>
#include <vector>

namespace Json {
  class Value;
}

namespace kratos {
namespace util {

// split string by any character in 'delim' and save sub-string to 'result'
// @param src source string
// @param delim delimeter
// @param result sub-string result
extern void splitOf(const std::string &src, const std::string &delim,
                    std::vector<std::string> &result);
// split string by 'delim' and save sub-string to 'result'
// @param src source string
// @param delim delimeter
// @param result sub-string result
extern void split(const std::string &src, const std::string &delim,
                  std::vector<std::string> &result);
// split string by 'delim' and save sub-string to 'result', the 'delim' will
// keep in result
// @param src source string
// @param delim delimeter
// @param result sub-string result
extern void splitBy(const std::string &src, char delim,
                    std::vector<std::string> &result);
// Is 'src' end with 's'
// @retval true
// @retval false
extern bool endWith(const std::string &src, const std::string &s);
// Is 'src' start with 's'
// @retval true
// @retval false
extern bool startWith(const std::string &src, const std::string &s);
// erase sub-string 's' from 'src'
// @param src source string
// @param s target sub-string
// @return new string
extern std::string remove(const std::string &src, const std::string &s);
// erase character in 'delim' from 'src' at left side and right side
// @param src source string
// @param delim delimeter
// @return new string
extern std::string trim(const std::string &src, const std::string &delim = " ");
// erase character in 'delim' from 'src' at left side
// @param src source string
// @param delim delimeter
// @return new string
extern std::string ltrim(const std::string &src,
                         const std::string &delim = " ");
// erase character in 'delim' from 'src' at right side
// @param src source string
// @param delim delimeter
// @return new string
extern std::string rtrim(const std::string &src,
                         const std::string &delim = " ");
// replace 'pattern' in 'src' with 'dest'
// @param src source string
// @param pattern the sub-string needs replacing
// @param dest replaced sub-string
// @return new string
extern std::string replace(const std::string &src, const std::string &pattern,
                           const std::string &dest);
// returns file name but not include extension
// eg. ab/c.txt -> c
// @param src source string
extern std::string get_file_name(const std::string &src);
/**
 * Returns file name
 * eg. ab/c.txt -> c.txt
 */
extern std::string get_file_full_name(const std::string &src);
/**
 * returns path of src
 * 
 * e.g. a/b/c/file.ext -> a/b/c
 */
extern std::string get_path(const std::string &src);
// Returns true if has the sub string
extern bool has_sub_string(const std::string &src, const std::string &sub);

/**
 * @brief 检测是否是一个数字，包含整数，浮点数
 */
extern bool isnumber(const std::string &s);
/**
 * @brief 检测是否是IPV4地址
 */
extern bool is_ip_address(const std::string &s);
/**
 * @brief 检测是否是域名
 */
extern bool is_domain_address(const std::string &s);
/**
 * 检测是否是合法的主机配置, ip:port.
 */
extern bool is_valid_host_config(const std::string &s);
/**
 * 检查并获取主机配置, ip:port.
 */
extern bool get_host_config(const std::string &s, std::string &ip, int &port);
/**
 * 将编译器产生的名字转化为人可读的名字.
 */
extern std::string demangle(const std::string &name);
/**
 * 是否是日期格式: "%4d/%2d/%2d %2d:%2d:%2d".
 */
extern bool is_date_string_fmt1(const std::string &date_string);
/**
 * 是否是日期格式: "%4d-%2d-%2d %2d:%2d:%2d".
 */
extern bool is_date_string_fmt2(const std::string &date_string);
/**
 * 转换为人可读的字符串
 */
extern std::string readable_size(std::size_t size);
/**
 * 从人可读的字符串转换为长度
 */
extern std::size_t from_readable_size_string(const std::string& size_string);
/**
 * 解析JSON串并获取根对象
 * 
 * \return true或false
 */
extern bool get_json_root(const std::string &json_string, Json::Value &root,
  std::string& error);
/**
 * 解析JSON文件并获取根对象
 * 
 * \return true或false
 */
extern bool get_json_root_from_file(const std::string &json_file_path, Json::Value &root,
  std::string& error);

} // namespace util
} // namespace kratos
